package xyz.bali16.module.article.controller;


import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gitee.starblues.bootstrap.annotation.AutowiredType;
import com.gitee.starblues.spring.MainApplicationContext;
import com.gitee.starblues.spring.SpringBeanFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import xyz.bali16.application.constant.ForumConstant;
import xyz.bali16.application.core.enums.ApiEnum;
import xyz.bali16.application.core.model.Result;
import xyz.bali16.application.core.model.UserVo;

import xyz.bali16.application.entity.User;
import xyz.bali16.application.service.UserService;
import xyz.bali16.module.article.entity.Article;
import xyz.bali16.module.article.entity.Comment;
import xyz.bali16.module.article.model.collection.CollectionPageParam;
import xyz.bali16.module.article.model.comment.CommentAddParam;
import xyz.bali16.module.article.model.comment.CommentPageParam;
import xyz.bali16.module.article.model.comment.CommentUpdateParam;
import xyz.bali16.module.article.model.comment.CommentPageVo;
import xyz.bali16.module.article.model.like.LikePageParam;
import xyz.bali16.module.article.service.*;
import xyz.bali16.module.article.utils.PageUtils;
import xyz.bali16.module.article.utils.ResultUtils;


import javax.validation.Valid;
import java.util.*;

import static xyz.bali16.application.core.model.Result.*;

/**
 * @author bali2 on 15/3/2023.
 * @version 1.0
 */
@RestController
@RequestMapping(BaseController.API + "comment")
@Api(tags = "评论接口")
@AllArgsConstructor
public class CommentController {

    public static final Logger logger = LoggerFactory.getLogger(CommentController.class);
    @Autowired
    private CommentService commentService;

    @Autowired
    private ArticleService articleService;
    @Autowired
    LikeService likeService;
    @Autowired
    CollectionService collectionService;
    @Autowired
    private MainApplicationContext context;

    private ActiveUserServiceCaller activeUserServiceCaller;

    private MuteServiceCaller muteServiceCaller;

    @Autowired
    ArticleRankServiceCaller articleRankServiceCaller;

    public PageUtils setComment(CommentPageParam param) {
        String userId = param.getUserId();
        //// 该用户的评论/回复总数
        //int commentCounts = commentService.getUserCommentCount(userId);
        // 分页查询
        IPage<Comment> commentIPage = commentService.getPage(param);
        PageUtils commentPage = new PageUtils(commentIPage);
        List<Comment> list = (List<Comment>) commentPage.getList();
        System.out.println("listA");
        System.out.println(list);
        // 封装评论和该评论对应的帖子信息

        List<Map<String, Object>> comments = new ArrayList<>();
        if (list != null) {
            // 获取符合条件的分页评论
            for (Comment comment : list) {
                Map<String, Object> map = new HashMap<>();

                map.put("test", "1");
                // 显示评论/回复对应的文章信息
                Article article = null;
                if (comment.getEntityType() == ForumConstant.ENTITY_TYPE_POST) {
                    // 如果是对帖子的评论，则直接查询 target_id 即可
                    article = articleService.getById(comment.getEntityId());
                    map.put("article", article);
                } else if (comment.getEntityType() == ForumConstant.ENTITY_TYPE_COMMENT) {
                    // 如过是对评论的回复，则先根据该回复的 target_id 查询评论的 id, 再根据该评论的 target_id 查询帖子的 id
                    Comment targetComment = commentService.getById(comment.getEntityId());
                    article = articleService.getById(targetComment.getEntityId());
                    map.put("article", article);
                }

                // 获取回复者用户信息
                SpringBeanFactory factory = context.getSpringBeanFactory();
                UserService userService = factory.getBean(UserService.class);
                System.out.println("chaoxian");
                System.out.println(param);
                User replyUser = userService.getById(comment.getUserId());
                UserVo userVo = new UserVo();
                BeanUtils.copyProperties(replyUser, userVo);
                comment.setUserVo(userVo);
                System.out.println("cur_comment");
                System.out.println(comment);
                Wrapper<Comment> wrapper = Wrappers.<Comment>lambdaQuery().eq(Comment::getEntityId, comment.getId());
                List<Comment> subComments = commentService.list(wrapper);


                System.out.println("subComments");
                System.out.println(subComments);
                if (!CollectionUtils.isEmpty(subComments)) {
                    comment.setChildrens(subComments);
                    comment.setChildrenCount(subComments.size());
                    for (Comment subComment : subComments) {
                        CommentPageParam commentPageParam = new CommentPageParam();
                        BeanUtils.copyProperties(param, commentPageParam);
                        BeanUtils.copyProperties(subComment, commentPageParam);
                        System.out.println("commentPageParam:");
                        System.out.println(commentPageParam);
                        SpringBeanFactory factory2 = context.getSpringBeanFactory();
                        UserService userService2 = factory2.getBean(UserService.class);
                        User replyUser2 = userService2.getById(commentPageParam.getUserId());
                        UserVo userVo2 = new UserVo();
                        BeanUtils.copyProperties(replyUser2, userVo2);
                        subComment.setUserVo(userVo2);
                        setComment(commentPageParam);
                    }
                }

                map.put("comment", comment);

                //map.put("replyUser", userVo);

                comments.add(map);

            }
        }
        commentPage.setList(comments);
        return commentPage;
    }

    @GetMapping
    //@PreAuthorize("@auth.permission('plugin:article:comment:query')")
    @ApiOperation("获取个人评论")
    public Result<CommentPageVo> getComment(@Valid CommentPageParam param) {
        try {
            CommentPageVo commentPageVo = new CommentPageVo();
            PageUtils commentPageUtils = setComment(param);
            commentPageVo.setPageUtils(commentPageUtils);
            commentPageVo.setCommentCount(commentPageUtils.getTotalCount());
            return success(ApiEnum.GET_SUCCESS, commentPageVo);
        } catch (Exception e) {
            e.printStackTrace();
            //ResultUtils.errorLog(logger, e, "获取个人评论 '{}' 评论失败 {}", param.getUserId(), e.getMessage());
            return failure(ApiEnum.GET_ERROR, "获取个人评论失败", e);
        }
    }

    @PostMapping
    //@PreAuthorize("@auth.permission('plugin:article:comment:add')")
    public Result<String> addComment(@RequestBody @Valid CommentAddParam param) {
        try {
            if(muteServiceCaller.isMute(param.getUserId())){
                failure("评论失败,你已被禁言");
            }
            //SpringBeanFactory factory = context.getSpringBeanFactory();
            //UserService userService = factory.getBean(UserService.class);
            //User user = userService.getByUsername(AuthUtils.getCurrentUsername());
            commentService.addComment(param);
            activeUserServiceCaller.addReplyNum(param.getUserId());
            // 更新评论数
            Article article = articleService.getById(param.getEntityId());
            article.setCommentCount(article.getCommentCount() + 1);
            articleService.updateById(article);
            // 本周热议数量加一
            LikePageParam likePageParam = new LikePageParam();
            likePageParam.setTargetId(article.getId());
            likePageParam.setCurrent(0);
            likePageParam.setSize(10);
            Integer likeNum = (int) likeService.getPage(likePageParam).getTotal();

            CollectionPageParam collectionPageParam = new CollectionPageParam();
            collectionPageParam.setTargetId(article.getId());
            collectionPageParam.setCurrent(0);
            collectionPageParam.setSize(10);
            Integer collectNum = (int) collectionService.getPage(collectionPageParam).getTotal();


            articleRankServiceCaller.incrTypeCountAndUnionForWeekRank("commentCount", param.getEntityId(), article.getTitle(), article.getCommentCount(), article.getViews(), article.getGmtCreated(), likeNum, collectNum, true);

            return success(ApiEnum.ADD_SUCCESS, "");
        } catch (Exception e) {
            e.printStackTrace();
            //ResultUtils.errorLog(logger, e, "添加评论评论 '{}' 失败. {}", param.getEntityId(), e.getMessage());
            return failure(ApiEnum.ADD_ERROR, e);
        }
    }

    @PutMapping
    //@PreAuthorize("@auth.permission('plugin:article:comment:update')")
    @ApiOperation("修改个人评论")
    public Result<String> update(@RequestBody @Valid CommentUpdateParam param) {
        try {
            commentService.updateComment(param);
            return response(ApiEnum.UPDATE_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            //ResultUtils.errorLog(logger, e, "更新个人评论 '{}' 评论失败 {}", param.getUserId(), e.getMessage());
            return failure(ApiEnum.UPDATE_ERROR, "更新个人评论失败", e);
        }
    }

    @DeleteMapping("/{commentId}")
    //@PreAuthorize("@auth.permission('plugin:article:comment:delete')")
    @ApiOperation("删除个人评论")
    @ApiImplicitParam(name = "userId", value = "个人评论id", paramType = "path", required = true)
    @Transactional
    public Result<String> deleteComment(@PathVariable("commentId") String commentId) {
        try {
            commentService.delete(commentId);
            return response(ApiEnum.DELETE_SUCCESS);
        } catch (Exception e) {
            e.printStackTrace();
            ResultUtils.errorLog(logger, e, "删除个人评论 '{}' 失败. {}", commentId, e.getMessage());
            return failure(ApiEnum.DELETE_ERROR, e);
        }
    }

}
